When you implement IComparable
or IComparable<T>
on a class you should also override Equals(object)
and overload the comparison operators (==
, !=
, <
, <=
, >
,
>=
). That’s because the CLR cannot automatically call your CompareTo
implementation from Equals(object)
or
from the base comparison operator implementations. Additionally, it is best practice to override GetHashCode
along with
Equals
.
This rule raises an issue when a class implements IComparable
without also overriding Equals(object)
and the comparison
operators.
Noncompliant code example
public class Foo: IComparable // Noncompliant
{
public int CompareTo(object obj) { /* ... */ }
}
Compliant solution
public class Foo: IComparable
{
public int CompareTo(object obj) { /* ... */ }
public override bool Equals(object obj)
{
var other = obj as Foo;
if (object.ReferenceEquals(other, null))
{
return false;
}
return this.CompareTo(other) == 0;
}
public int GetHashCode() { /* ... */ }
public static bool operator == (Foo left, Foo right)
{
if (object.ReferenceEquals(left, null))
{
return object.ReferenceEquals(right, null);
}
return left.Equals(right);
}
public static bool operator > (Foo left, Foo right)
{
return Compare(left, right) > 0;
}
public static bool operator < (Foo left, Foo right)
{
return Compare(left, right) < 0;
}
public static bool operator != (Foo left, Foo right)
{
return !(left == right);
}
}